package com.weipai.demo.util;


import com.weipai.demo.enums.RetCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.util.List;

/**
 * @author songmengqiang
 * @create 2018-09-13 14:34
 **/
@RestControllerAdvice
public class ExceptionAdvice {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @ExceptionHandler({Throwable.class})
    public Response handleAllException(Throwable e) {
        Response response = new Response();
        e.printStackTrace();
        response.setCode(RetCode.REQUEST_ERROR);
        response.put("errMsg", e.getClass().getSimpleName() + ":" + e.getMessage());
        return response;
    }

    /**
     * 处理请求对象属性不满足校验规则的异常信息
     *
     * @param request
     * @param exception
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Response exception(HttpServletRequest request, MethodArgumentNotValidException exception) {
        BindingResult result = exception.getBindingResult();
        final List<FieldError> fieldErrors = result.getFieldErrors();
        StringBuilder builder = new StringBuilder();

        for (FieldError error : fieldErrors) {
            builder.append(error.getDefaultMessage() + "\n");
        }
        Response response = new Response();
        response.setCode(RetCode.REQUEST_ERROR);
        response.setData(builder.toString());
        return response;
    }

    /**
     * 处理请求单个参数不满足校验规则的异常信息
     *
     * @param request
     * @param exception
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    public Response constraintViolationExceptionHandler(HttpServletRequest request, ConstraintViolationException exception) {
        logger.info(exception.getMessage());
        Response response = new Response();
        response.setCode(RetCode.REQUEST_ERROR);
        String[] fields = exception.getMessage().split(",");
        String sf = "";
        for (String field : fields){
            String[] newSf = field.split(":");
            if(sf.equals("")){
                sf += newSf[1];
            }else{
                String s = "," + newSf[1];
                sf += s;
            }
        }
        response.setData(sf);
        return response;
    }

    @ExceptionHandler(BindException.class)
    public Response BindException(BindException e) {
        logger.error(e.getMessage(), e);
        Response response = new Response();
        response.setCode(RetCode.REQUEST_ERROR);
        response.setData(validation(e.getBindingResult()));
        return response;
    }

    private String validation(BindingResult bindingResult) {
        List<ObjectError> errors = bindingResult.getAllErrors();
        StringBuilder sb = new StringBuilder("");
        if (!CollectionUtils.isEmpty(errors)) {
            for (ObjectError error : errors) {
                FieldError fieldError = (FieldError) error;
                //sb.append(fieldError.getField() + fieldError.getDefaultMessage() + ",");
                sb.append(fieldError.getDefaultMessage() + ",");
            }
        }
        return sb.length()>0?sb.substring(0,sb.length()-1):sb.toString();
    }
}
